# # 新需求
#
# A = 'AAAAAAAAAAAAAAAAAAAAAAAAAA'
# def add():
#     for i in range(3):
#         print(A)
# (add())
#
# print(2)
# (add())
#
# print(3)
# (add())
# # 函数名的命名规则： 就是标识符
# # 需求: 封装函数，输出：今天天气真好， 适合好好学习
# print(111)   # 这行代码是为了debug调试，没有实际意义
# def add1():
#     print('今天天气真好, 适合好好学习')
# add()
# #  TODO 调用函数
# # # 函数名()
# # info()
# # 函数参数
#
# # 需求1： 用函数封装一个 求 2 和 3的和的功能
# # 函数定义
# def add3():
#     print(2 + 3)
# add3()
# # 需求2：用函数封装一个 求 1 和 2的和的功能
# def add4():
#     print(1 + 2)
# add4()
# # 调用
# add()
# # 需求3: # 需求2：用函数封装一个 求 2 和 2的和的功能
# def cd():
#     print(2 + 2)
# cd()
# print("-" * 20)
# # 需求4: # 需求2：用函数封装一个 求 2 和 2的和的功能
# # # TODO 参数
# # # 函数定义
# def ok(a , b): #函数定义时为形参
#     print(a + b)
# ok(200, 200000) #  # 函数调用时的参数叫做实际参数：实参44
# # 需求： 求2个数的和
# # 函数返回
# # 在函数提中: return 要返回的数据
# # 函数定义
# def add5(a, b):   # 函数定义时的参数叫做形式参数：形参
#     result = a + b
#     return result
#
#
# print(add5(1, 2))
# result = add5(1 , 2)
# print(result)
# # 需求： 求2个数的和
# print(11)   # 为了debug
#
#
# def add(a, b):
#     print(a + b)   # 3
#     return a + b
#
# print(add(1, 2))
# print(add(1,2) + add(3, 4))
# # pass语句
# # if
# if 1 == 2:
#     pass
#
# i = 1
# while i <= 3:
#     pass
#     i += 1
# for i in range(2):
#     pass
# # TODO 函数注释（函数说明文档）
# # 需求： 求2个数的和
# def i(a, b):
#     '''
#     求两个数的和
#     :param a: int
#     :param b: int
#     :return: int 求和的结果
#     '''
#     return a + b
# print(i(1 , 2))
# help(i)
# help(print())
# help(max)
#  # 匿名函数 lambda表达式
# # 语法：
# # lambda [param1, param2, ...] : 表达式
# # 需求： 求2个整数的和
# # 把lambda赋值给变量使用
# add = lambda a, b:a + b
# print(add(1 , 2))
# result = (lambda a, b:a + b)(1, 2) # 自调用
# print(result)
# # 需求：求2个整数的运算（加减乘除）
# def operator_two_num(a, b, oprator):
#     """
#     2个整数的运算
#     :param a: 第一个整数
#     :param b: 第二个整数
#     :param oprator: 进行运算操作的函数
#     :return: 运算的结果
#     """
#     return oprator(a, b)
#
#
# # 加法
# def add(a, b):
#     return a + b
#
# # 减法
# def subtraction(a, b):
#     return a - b
#
# # 1和2的加法运算
# result = operator_two_num(1, 2, add)
# print(result)
#
# # 2-1
# result = operator_two_num(2, 1, subtraction)
# print(result)
#
# # TODO 把匿名函数传入
# print('--' * 20)
# print(operator_two_num(1, 2, lambda a, b: a + b))
# print(operator_two_num(2, 1, lambda a, b: a - b))
# print(operator_two_num(2, 1, lambda a, b: a * b))
# print(operator_two_num(2, 1, lambda a, b: a // b))
# print(operator_two_num(2, 1, lambda a, b: a % b))

# 函数可以当作参数或者返回值使用

def fn1(a):
    return a()

m = 1
n = 'abc'
def test():
    return 1 + 1

# 函数定义
# TODO 必填参数
def fn1(a, b):
    print(a, b)

# 函数调用
# 必填参数必须传入， 否则就抛出：TypeError: fn1() missing 2 required positional arguments
# fn1(1, 2)TODO 传参方式
# # -- 位置传参
def fng1(a, b):
    print(a, b)


(fng1(1, 2))#位置传参
(fng1(a=200,b=100)) #关键字传参



# TODO 默认参数[缺省参数]
# 注意：默认参数要放在必填参数的后面
# 错误信息： SyntaxError: non-default argument follows default argument
def add_stu(name, age,addr = '湖北'):
    print(name,age,addr)
add_stu('朱梓骁',18)

# 函数调用
add_stu(addr = 'hubei', name = '柱子', age = 19)
add_stu(age = 18, name = '王琳')
# TODO *args 位置不定长参数
# 定义
def add1(*args):
    print(args)
add1('a','b',15,20)
# TODO **kwargs 关键字不定长参数
def add2(**kwargs):
    print(kwargs)
add2(age = 18, name = '王克勤', duanwei = '铂金')
#TODO 万能参数
def zhu1(*args,**kwargs):
    print(args)
    print(kwargs)
zhu1('a','b', 50, 'c', age = 18)
# 按照这个顺序来定义参数：必填参数、位置不定长参数、默认参数、关键字不定长参数
def zhu2(a, b, *args, china = '中国', **kwargs):
    print(a,b)
    print(*args)
    print(china)
    print(kwargs)

zhu2(1 , 'abc','chana', 5, china = '韩国', gae = '19')
# TODO 拆包 - 位置参数
def zz1(a, b, c):
    print(a, b, c)
tuple1 =(1, 2 , 3,)
zz1(*tuple1)
# TODO 拆包- 关键字参数
tuple5 = {'a':100, 'b':200, 'c':300}
zz1(**tuple5)
def zz2(*aa,**aaa):
    print(aa)
    print(aaa)
zz2(*tuple1,**tuple5)
 # TODO 函数返回None
# 第一种
def fn1():
    pass
print(fn1())


# 第二种
def fn2():
    return
print(fn2())
# TODO
# 函数同时返回多个值#
def fn3():
    return 'a', 'b', 'c'
rn1 = fn3()
print(type(rn1), rn1)
a, b, c = fn3()
print(a, b, c)




















